package com.erli.exchange.core.util;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpsUtils {

	private static final Logger LOGGER = LoggerFactory.getLogger(HttpsUtils.class);

	public static final int DEFAULT_CONNECT_TIMEOUT = 10 * 1000;

	public static final int DEFAULT_READ_TIMEOUT = 10 * 1000;

	private static class TrustAnyTrustManager implements X509TrustManager {

		@Override
		public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
				throws java.security.cert.CertificateException {

		}

		@Override
		public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
				throws java.security.cert.CertificateException {

		}

		@Override
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			return new java.security.cert.X509Certificate[0];
		}
	}

	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}

	public static String post(String url, String content, String charset)
			throws NoSuchAlgorithmException, KeyManagementException, IOException {
		return post(url, content, charset, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT);
	}

	/**
	 * post方式请求服务器(https协议)
	 * @param url
	 *            请求地址
	 * @param content
	 *            参数
	 * @param charset
	 *            编码
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws IOException
	 */
	public static String post(String url, String content, String charset, int connectTimeoutSeconds,
			int readTimeoutSeconds) throws NoSuchAlgorithmException, KeyManagementException, IOException {
		SSLContext sc = SSLContext.getInstance("SSL");
		sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());

		URL console = new URL(url);
		HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
		conn.setConnectTimeout(connectTimeoutSeconds * 1000);
		conn.setSSLSocketFactory(sc.getSocketFactory());
		conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
		conn.setReadTimeout(readTimeoutSeconds * 1000);
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.connect();
		DataOutputStream out = null;
		InputStream is = null;
		try {
			out = new DataOutputStream(conn.getOutputStream());
			out.write(content.getBytes(charset));
			// 刷新、关闭
			out.flush();
			is = conn.getInputStream();
			if (is != null) {
				ByteArrayOutputStream outStream = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int len;
				while ((len = is.read(buffer)) != -1) {
					outStream.write(buffer, 0, len);
				}
				return new String(outStream.toByteArray());
			}
		} catch (IOException e) {
			LOGGER.error("https请求IO异常, {}, {}", url, content, e);
		} catch (Exception e) {
			LOGGER.error("https请求异常, {}, {}", url, content, e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (Exception e) {
					LOGGER.error("https请求关闭is异常, {}, {}", url, content, e);
				}
			}

			if (out != null) {
				try {
					out.close();
				} catch (Exception e) {
					LOGGER.error("https请求关闭out异常, {}, {}", url, content, e);
				}
			}
		}
		return null;
	}
}
